﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace Qetza.TeamFoundation.Build.Workflow.Activities
{
    /// <summary>
    /// Represents the versioning settings.
    /// </summary>
    [Serializable]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class VersioningSettings
    {
        #region Properties

        /// <summary>
        /// Gets or sets the search pattern for locating AssembyInfo files to update.
        /// </summary>
        /// <value>
        /// The search pattern for locating AssembyInfo files to update.
        /// </value>
        [DisplayName(@"AssemblyInfo Filespec")]
        [Description(@"Specifiy the search pattern for locating AssemblyInfo files - e.g. **\*AssemblyInfo*.cs.")]
        [RefreshProperties(RefreshProperties.All)]
        [Browsable(true)]
        public string AssemblyInfoFileSpec { get; set; }

        /// <summary>
        /// Gets or sets the assembly version format.
        /// </summary>
        /// <value>
        /// The assembly version format.
        /// </value>
        [DisplayName("AssemblyVersion Format")]
        [Description("Specify the AssemblyVersion format. Supported tokens are: $(current), $(increment), $(date:<format>).")]
        [RefreshProperties(RefreshProperties.All)]
        [Browsable(true)]
        public string AssemblyVersionFormat { get; set; }

        /// <summary>
        /// Gets or sets the assembly file version format.
        /// </summary>
        /// <value>
        /// The assembly file version format.
        /// </value>
        [DisplayName("AssemblyFileVersion Format")]
        [Description("Specify the AssemblyFileVersion format. Supported tokens are: $(current), $(increment), $(date:<format>).")]
        [RefreshProperties(RefreshProperties.All)]
        [Browsable(true)]
        public string AssemblyFileVersionFormat { get; set; }

        /// <summary>
        /// Gets or sets the assembly informational version format.
        /// </summary>
        /// <value>
        /// The assembly informational version format.
        /// </value>
        [DisplayName("AssemblyInformationalVersion Format")]
        [Description("Specify the AssemblyInformationalVersion format. Supported tokens are: $(version), $(fileversion), $(date:<format>).")]
        [RefreshProperties(RefreshProperties.All)]
        [Browsable(true)]
        public string AssemblyInformationalVersionFormat { get; set; }

        /// <summary>
        /// Indicates whether search pattern is specified.
        /// </summary>
        /// <value>
        /// <b>true</b> if search pattern is specified; otherwise <b>false</b>.
        /// </value>
        [Browsable(false)]
        public bool HasAssemblyInfoFileSpec
        {
            get
            {
                return !string.IsNullOrEmpty(this.AssemblyInfoFileSpec);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Returns a <see cref="String"/> that represents the current <see cref="VersioningSettings"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="String"/> that represents the current <see cref="VersioningSettings"/>.
        /// </returns>
        public override string ToString()
        {
            if (this.HasAssemblyInfoFileSpec)
            {
                var args = new List<string>();
                if (!string.IsNullOrEmpty(this.AssemblyVersionFormat))
                {
                    args.Add(
                        string.Format("'{0}' for version", this.AssemblyVersionFormat)
                        );
                }

                if (!string.IsNullOrEmpty(this.AssemblyFileVersionFormat))
                {
                    args.Add(
                        string.Format("'{0}' for file version", this.AssemblyFileVersionFormat)
                        );
                }

                if (!string.IsNullOrEmpty(this.AssemblyInformationalVersionFormat))
                {
                    args.Add(
                        string.Format("'{0}' for informational version", this.AssemblyInformationalVersionFormat)
                        );
                }

                if (args.Count != 0)
                {
                    return string.Format(
                        "Update AssemblyInfo files matching '{0}' using {1}",
                        this.AssemblyInfoFileSpec,
                        args.Aggregate((a1, a2) => a1 + ", " + a2)
                        );
                }
                else
                {
                    return string.Format("Update AssemblyInfo files matching '{0}'", this.AssemblyInfoFileSpec);
                }
            }

            return string.Empty;
        }

        #endregion
    }
}
